// 策略模式
var calculateBonus_0 = function(performanceLevel, salary) {
    if (performanceLevel === 'S') {
        return salary * 4;
    }

    if (performanceLevel === 'A') {
        return salary * 3;
    }

    if (performanceLevel === 'B') {
        return salary * 2;
    }
}

console.log(calculateBonus_0('S', 10000));
console.log(calculateBonus_0('B', 10000));
console.log(calculateBonus_0('A', 10000));

/**
 * 上述代码存在：
 * 1、calculateBonus 函数比较庞大，包含了很多if-eles语句，这些语句需要覆盖所有的业务逻辑
 * 2、calculateBonus 函数缺乏弹性，如果新增或者调整计算方法，这需要重新修改calculateBonus函数
 * 3、计算的逻辑复用性差，无法在其他程序中进行服用
 */

 // 第一次优化
 var performanceS = function(salary) {
     return salary * 5;
 }
 var performanceA = function(salary) {
     return salary * 3;
 }
 var performanceB = function(salary) {
     return salary * 2;
 }
 var calculateBonus_1 = function(performanceLevel, salary) {
    if (performanceLevel === 'S') {
        return performanceS(salary)
    }
    if (performanceLevel === 'A') {
        return performanceA(salary)
    }
    if (performanceLevel === 'B') {
        return performanceB(salary)
    }
 }
console.log(calculateBonus_1('A', 10000))
console.log(calculateBonus_1('S', 10000))
console.log(calculateBonus_1('B', 10000))

/**
 * 上述代码第一次优化后还存在问题：
 * 1、calculateBonus 函数还是会越来越大
 * 2、系统需求变化时calculateBonus函数缺乏弹性
 */

 // 第二次优化：使用策略模式来优化
 /**
  * 策略模式指的是定义一系列的算法，把他们一个个的封装起来。将不变的部分与变化的部分分开始每个设计模式的主题，策略模式也是如此，就是将算法的使用与算法的实现分离开来
  * 基于策略模式的程序至少由两部分组成，第一部分是策略类，策略类封装了具体的算法，并负责具体的计算过程。第二部分是环境类context，context接受客户的请求，随后吧请求委托给某个策略类。
  */

var PerformanceS = function() {}
PerformanceS.prototype.calculate = function(salary) {
    return salary * 5;
}

var PerformanceA = function() {}
PerformanceA.prototype.calculate = function(salary) {
    return salary * 4;
}

var PerformanceB = function() {}
PerformanceB.prototype.calculate = function(salary) {
    return salary * 3;
}

var Bonus = function() {
    this.salary = null;
    this.strategy = null;
}

Bonus.prototype.setSalary = function(salary) {
    this.salary = salary
}

Bonus.prototype.setStratery = function(stratery) {
    this.strategy = stratery;
}

Bonus.prototype.getBonus = function() {
    return this.strategy.calculate(this.salary);
}

var bonus = new Bonus();
bonus.setSalary(10000);
bonus.setStratery(new PerformanceS());

console.log(bonus.getBonus());

/**
 * 策略模式：定义一系列的算法，把他们一个个的封装起来，将算法的实现与算法的使用分离开来，并使算法可以相互替换
 */

 // javascript中的算法
 var strategies = {
     'A': function(salary) {
         return salary * 3;
     },
     'B': function(salary) {
         return salary * 2;
     },
     'S': function(salary) {
         return salary * 5;
     }
 }

 var calculateBonus_2 = function(level, salary) {
     return strategies[level](salary);
 }
console.log(calculateBonus_2('S', 30000))
console.log(calculateBonus_2('A', 30000))
console.log(calculateBonus_2('B', 30000))

// 使用策略模式实现小球的缓动动画
/**
 * t: 小球已运动的时间
 * b：小球开始位置
 * c：目标位置
 * d：持续的时间
 */